package cn.edu.zime.tjh.handler;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;

import java.net.InetSocketAddress;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

public class AsyncUDPServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {
    private Consumer<String> logCallback;
    private static final ConcurrentHashMap<String, InetSocketAddress> clients = new ConcurrentHashMap<>();
    
    public AsyncUDPServerHandler(Consumer<String> logCallback) {
        this.logCallback = logCallback;
    }
    
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        // 获取发送方地址
        InetSocketAddress sender = packet.sender();
        String clientKey = sender.getAddress().getHostAddress() + ":" + sender.getPort();
        
        // 记录客户端
        clients.put(clientKey, sender);
        
        // 读取数据
        ByteBuf content = packet.content();
        String received = content.toString(CharsetUtil.UTF_8);

        String logMessage = String.format("UDP服务器收到 [%s:%d]: %s",
                sender.getAddress().getHostAddress(),
                sender.getPort(),
                received);
        
        if (logCallback != null) {
            logCallback.accept(logMessage);
        }

        // 创建回显数据包（原样返回）
        ByteBuf buf = ctx.alloc().buffer();
        buf.writeCharSequence(received, CharsetUtil.UTF_8);
        DatagramPacket response = new DatagramPacket(buf, sender);

        // 发送回显
        ctx.writeAndFlush(response);
        
        if (logCallback != null) {
            logCallback.accept("UDP服务器回显给 [" + clientKey + "]: " + received);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        if (logCallback != null) {
            logCallback.accept("UDP服务器错误: " + cause.getMessage());
        }
        cause.printStackTrace();
    }
    
    public static ConcurrentHashMap<String, InetSocketAddress> getClients() {
        return clients;
    }
    
    public static void clearClients() {
        clients.clear();
    }
}